#include <SPI.h>
#include <PN532_SPI.h>
#include <PN532Interface.h>
#include <PN532.h>
#include "PN532_debug.h"
PN532_SPI pn532spi(SPI, 10);
PN532 nfc(pn532spi);
//uint8_t select_mainpackage_Apdu[] = {    0x00, /* CLA */
//                              0xA4, /* INS */
//                              0x00, /* P1  */
//                              0x00, /* P2  */
//                              0x02, /* Length of AID  */
//                              0xEC,0x11 ,
//                              0x00 /* Le  */ };
//  uint8_t selectApdu[] = {    0x00, /* CLA */
//                              0xA4, /* INS */
//                              0x00, /* P1  */
//                              0x00, /* P2  */
//                              0x02, /* Length of AID  */
//                              0xEC,0x01 ,
//                              0x00 /* Le  */ };
//    uint8_t select_subsidies_Apdu[] = {    0x00, /* CLA */
//                              0xA4, /* INS */
//                              0x00, /* P1  */
//                              0x00, /* P2  */
//                              0x02, /* Length of AID  */
//                              0xEC,0x12 ,
//                              0x00 /* Le  */ };
//   uint8_t getbalanceApdu[] = {    0x80,
//                              0x5C,
//                              0x00,
//                              0x02,
//                              0x04
//                      };
//   uint8_t getASNApdu[] = {    0x00,
//                              0xB0,
//                              0x95,
//                              0x0A,
//                              0x0A
//                          };
//     uint8_t get_std_num_Apdu[] = {    0x00,
//                              0xB0,
//                              0x96,
//                              0x84,
//                              0x14
//                          };
// uint8_t select_CARDNO_Apdu[] = { 0x00,
//                              0xB0,
//                              0x82,
//                              0x01,
//                              0x09
//                               };

bool bool_readuid = true;  //是否需要读UID，true需要读UID，false不需要读UID
bool flag_alreadystart=false; //是否收到过开始指令，
bool flag_receive_res = false; //收到的是否为响应

bool flag_send_APDU = false; //发送的是APDU
bool  flag_send_UID = false;// 发送的是UID
bool flag_just_send_connect= false;//刚刚发送的是connect指令，在错误处理时判断重发哪条指令。
bool flag_just_send_UID= false;// ..
bool flag_just_send_APDU= false;//..
bool flag_has_received_successresponse=false;//是否已经收到正确的响应，
uint8_t numOfResend=0;//重发的次数
uint8_t receivebytes[100];//收到主机的数据
uint8_t response[100];//卡片返回的数据
uint8_t receiveLength ;
uint8_t packageLength_send;//发送请求数据包长度
byte package[100];
uint8_t FLAG_2;//报文中的FLAG_2
//uint8_t APDU_received_Length;
bool success;
bool result;
uint8_t check_flag; //FLAG的判断标志，0为error,1为响应，2为请求
uint8_t responseLength = 100;
uint8_t RID = 0x01;
uint8_t  ParityCheckByte_receive_calculate;//收到主机数据的奇偶校验结果
uint8_t uid[7];  // Buffer to store the returned UID
uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
uint8_t success_status = (uint8_t)0x00;
uint8_t BEGIN_error_status = (uint8_t)0x81;
uint8_t get_UID_error_status = (uint8_t)0x82;
uint8_t set_UID_error_status = (uint8_t)0x83;
uint8_t RID_error_status = (uint8_t)0x84;
uint8_t APDU_error_status = (uint8_t)0x86;
uint8_t FLAG_error_status = (uint8_t)0x89;
uint8_t ParityCheck_error_status = (uint8_t)0x8A;
void setup()
{
  Serial.begin(115200);
  // DMSG_STR_MINE("-------Peer to Peer HCE--------");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    DMSG_MINE("Didn't find PN53x board");
    while (1); // halt
  }

  // Got ok data, print it out!
  //  DMSG_MINE("Found chip PN5"); DMSG_STR_MINE((versiondata>>24) & 0xFF, HEX);
  // DMSG_MINE("Firmware ver. "); DMSG_MINE((versiondata>>16) & 0xFF, DEC);
  // DMSG_MINE('.'); DMSG_STR_MINE((versiondata>>8) & 0xFF, DEC);

  // Set the max number of retry attempts to read from a card
  // This prevents us from waiting forever for a card, which is
  // the default behaviour of the PN532.
  // nfc.setPassiveActivationRetries(0xFF);

  // configure board to read RFID tags
  nfc.SAMConfig();
}

void loop()
{

  DMSG_STR_MINE("Waiting for an ISO14443A card");

  // set shield to inListPassiveTarget

  //delay(100);
  if (bool_readuid)
  {
    result = readUID();
    if (result)
    {
      bool_readuid = false;
       setup();
      send_UID_request_data();
        delay(5);
    }
    else
    {
       setup();
   
     // send_connect_request_data();

       delay(5);
     
      return;
    }
  }
  setup();
  DMSG_STR_MINE(" start looking for the card...");
  
  success = nfc.inListPassiveTarget();

  if (!success)
  {

    DMSG_STR_MINE("Didn't find anything!");
    //when the card is removed,UID need to be read again.
    bool_readuid = true;
    return;
  }

  else {

    DMSG_STR_MINE("Found something!");

    if(flag_alreadystart)
     {
       DMSG_STR_MINE("alreadystart~~~~~~~~~~");
     }
     else
     {


   //if command is START ,start the while;
      success=getDataFromLinux();
       if(!success)
       {
        DMSG_MINE("error at getDataFromLinux");
        return;
       }
        else if(!flag_has_received_successresponse)
        {
          delay(5);
          DMSG_MINE("did not receive successresponse");
           setup();
           return;
        }

       else if(FLAG_2==(uint8_t)0xd3)
             {

            DMSG_STR_MINE("START LISTENING!");
            flag_alreadystart=true;
            
             }
            else
            {
              setup();
            return;
            }
    }

    while (1)
    {
      success = getDataFromLinux();
      //error at receive DATA
    if (!success)
      {
        DMSG_STR_MINE("error at getDataFromLinux ");
        break;
      }
      //Success in receive DATA
      else {
        if (flag_receive_res)
        {
          DMSG_STR_MINE("receive response~~~~~~~~~~~");
          
         continue;
        }
        else if(!flag_has_received_successresponse)
        {
           DMSG_MINE("didnot receive successresponse");
           setup();
           continue;
        }
        DMSG_STR_MINE("333data received is");
        nfc.PrintHex_2(receivebytes, receiveLength);
        DMSG_STR_MINE("Success in receive DATA");
          delay(5);
        if (FLAG_2 == (uint8_t)0xd4)
        {
          DMSG_STR_MINE("STOP LISTENGING!");
           flag_alreadystart=false;
            setup();
          break;
        }
        else if(FLAG_2 == (uint8_t)0xd3)
        {
            setup();
           break;
        }
        
        else
        {
          success = doDataExchange();
          if (!success)
          {
            DMSG_STR_MINE("error at doDataExchange");

            break;
          }
          else {
            DMSG_STR_MINE("success at doDataExchange");
          }
        }
      }
    }
    delay(1000);
  }
}
void printResponse(uint8_t *response, uint8_t responseLength) {

  String respBuffer;

  for (int i = 0; i < responseLength; i++) {

    if (response[i] < 0x10)
      respBuffer = respBuffer + "0"; //Adds leading zeros if hex value is smaller than 0x10

    respBuffer = respBuffer + String(response[i], HEX) + " ";
  }

  DMSG_MINE("response: "); DMSG_STR_MINE(respBuffer);
}

void setupNFC() {

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    DMSG_MINE("Didn't find PN53x board");
    while (1); // halt
  }

  // Got ok data, print it out!
  //DMSG_MINE("Found chip PN5"); DMSG_STR_MINE((versiondata>>24) & 0xFF, HEX);
  //DMSG_MINE("Firmware ver. "); DMSG_MINE((versiondata>>16) & 0xFF, DEC);
  //DMSG_MINE('.'); DMSG_STR_MINE((versiondata>>8) & 0xFF, DEC);

  // configure board to read RFID tags
  nfc.SAMConfig();
}
void makeREQPackage(uint8_t *data, uint8_t data_length) {
  uint8_t beginOfPackage = (uint8_t)0x24;
  uint8_t endOfPackage = (uint8_t)0x23;
  uint8_t requestOfPackage = (uint8_t)0x00;
  uint8_t responseOfPackage = (uint8_t)0x01;
  uint8_t Flag_2_UIDOfPackage = (uint8_t)0xd1;
  uint8_t Flag_2_APDUOfPackage = (uint8_t)0xd2;

  package[0] = beginOfPackage;
  package[1] = beginOfPackage;

    package[2] = requestOfPackage;

  package[3] = RID;
  if (flag_send_APDU) {
    package[4] = Flag_2_APDUOfPackage;
    flag_send_APDU = false;
  }
  else {
    if (flag_send_UID)
    {
      package[4] = Flag_2_UIDOfPackage;
      flag_send_UID = false;
    }
    else {
      // return 0;
    }
  }
  package[5] = data_length;
  for (int i = 6; i < data_length + 6; i++)
  {
    package[i] = data[i - 6];
  }
  //  caculate ParityCheckByte
  uint8_t count[data_length + 4];
  //count the numnber of "1" in each byte
  for (int j = 0; j < data_length + 4; j++)
  {
    count[j] = bitcount (package[j + 2]);
    count[j] = (count[j] % 2) ? 1 : 0;

  }
  //add the ( numnber of "1" in each byte) if jishu ParityCheck_send=0x01;
  uint8_t sum = 0;
  for (int w = 0; w < data_length + 4; w++)
  {

    sum = sum + count[w];
  }
  uint8_t ParityCheckByte_send_calculate;
  ParityCheckByte_send_calculate = (sum % 2) ? (uint8_t)0x01 : (uint8_t)0x00;
  package[data_length + 6] = ParityCheckByte_send_calculate;
  //DMSG_MINE(ParityCheckByte_send_calculate);
  package[data_length + 7] = endOfPackage;
  //DMSG_MINE(package[data_length+7]);
  package[data_length + 8] = endOfPackage;


  packageLength_send = data_length + 9;
  //return package;
}
void makeREQ_Connect_Package() {
  uint8_t beginOfPackage = (uint8_t)0x24;
  uint8_t endOfPackage = (uint8_t)0x23;
  uint8_t requestOfPackage = (uint8_t)0x00;
  
  uint8_t Flag_2_ConnectOfPackage = (uint8_t)0xd5;
 

  package[0] = beginOfPackage;
  package[1] = beginOfPackage;

  package[2] = requestOfPackage;

  package[3] = RID;
  
  
  
  package[4] = Flag_2_ConnectOfPackage;
    
 
  

  //  caculate ParityCheckByte
  uint8_t count[3];
  //count the numnber of "1" in each byte
  for (int j = 0; j < 3; j++)
  {
    count[j] = bitcount (package[j + 2]);
    count[j] = (count[j] % 2) ? 1 : 0;

  }
  //add the ( numnber of "1" in each byte) if jishu ParityCheck_send=0x01;
  uint8_t sum = 0;
  for (int w = 0; w < 3; w++)
  {

    sum = sum + count[w];
  }
  uint8_t ParityCheckByte_send_calculate;
  ParityCheckByte_send_calculate = (sum % 2) ? (uint8_t)0x01 : (uint8_t)0x00;
  package[5] = ParityCheckByte_send_calculate;
  //DMSG_MINE(ParityCheckByte_send_calculate);
  package[6] = endOfPackage;
  //DMSG_MINE(package[data_length+7]);
  package[7] = endOfPackage;


  packageLength_send = 8;
  //return package;
}
void makeRESPackage(uint8_t status_response) {
  uint8_t beginOfPackage = (uint8_t)0x24;
  uint8_t endOfPackage = (uint8_t)0x23;

  uint8_t responseOfPackage = (uint8_t)0x01;


  package[0] = beginOfPackage;
  package[1] = beginOfPackage;

    package[2] = responseOfPackage;
  package[3] = RID;

  package[4] = status_response;

  //  caculate ParityCheckByte
  uint8_t count[3];
  //count the numnber of "1" in each byte
  for (int j = 0; j < 3; j++)
  {
    count[j] = bitcount (package[j + 2]);
    count[j] = (count[j] % 2) ? 1 : 0;

  }
  //add the ( numnber of "1" in each byte) if jishu ParityCheck_send=0x01;
  uint8_t sum = 0;
  for (int w = 0; w < 3; w++)
  {

    sum = sum + count[w];
  }
  uint8_t ParityCheckByte_send_calculate;
  ParityCheckByte_send_calculate = (sum % 2) ? (uint8_t)0x01 : (uint8_t)0x00;
  package[5] = ParityCheckByte_send_calculate;
  //DMSG_MINE(ParityCheckByte_send_calculate);
  package[6] = endOfPackage;
  //DMSG_MINE(package[data_length+7]);
  package[7] = endOfPackage;
 packageLength_send = 8;
  //return package;
}

void send_APDU_request_data() {

  flag_send_APDU = true;

  makeREQPackage(response,responseLength);
  //nfc.PrintHex_3(package, packageLength_send);
  Serial.write(package, packageLength_send);
  flag_just_send_APDU= true;
   flag_just_send_UID=false;
  flag_just_send_connect=false;
  flag_has_received_successresponse=false;
  //package the data and DMSG_MINE;
}

void send_UID_request_data() {

  flag_send_UID = true;
  makeREQPackage(uid, uidLength);
//nfc.PrintHex_3(package, packageLength_send);
  Serial.write(package, packageLength_send);
  flag_just_send_UID= true;
  flag_just_send_connect=false;
  flag_just_send_APDU=false;
  flag_has_received_successresponse=false;
}
void send_connect_request_data() {
  makeREQ_Connect_Package();
  //nfc.PrintHex_3(package, packageLength_send);
  Serial.write(package, packageLength_send);
  flag_just_send_connect= true;
  flag_just_send_UID=false;
  flag_just_send_APDU=false;
}
void send_response_package(uint8_t status_response) {

  makeRESPackage(status_response);
  //nfc.PrintHex_3(package, packageLength_send);
  Serial.write(package, packageLength_send);
}

void handlerror() {
    if(flag_just_send_UID)
    {
      send_UID_request_data();
      delay(5);
    }
    else if(flag_just_send_APDU)
    {
      send_APDU_request_data();
      delay(5);
    }
    else if(flag_just_send_connect)
    {
      //send_connect_request_data();
      delay(5);
    }
    numOfResend++;
}

bool watingPackagefromLinux() {
  bool flag = false;
  //set the largest time, if(waittime>largest time) return false;else receivedata();
  for (int i = 0; i < 2000; i++)
  {  
   //make sure the reader is connented
   //send_connect_request_data();

       
     
    if (Serial.available() > 0)
    {
      flag = true;
      break;
    }
    delay(10);
  }
  // if the reception of DATA is SUCCESS,return true;
  //else if ERROR,return false;

  if (flag)
    return true;
  else
    return false;

}
bool getPackageFromLinux() {
  //1)read Serial port;2)check the begin and end;3)do Parity Check;4)check flag ..follow the rules...
  // receivebytes=selectApdu;
  // receiveLength=(uint8_t)sizeof(selectApdu);

  // int i = 0;// length of data
  // while (Serial.available() > 0)
  // {
  //   receivebytes[i] = Serial.read();
  //   //delay(2);
  //   if (receivebytes[0] != (uint8_t)0x24)
  //   {
  //     continue;
  //   }
  //   else {
  //     i++;
  //     receivebytes[i] = Serial.read();
  //    // delay(2);
  //     if (receivebytes[1] != (uint8_t)0x24)
  //     {
  //       i = 0;
  //       continue;
  //     }
  //     else
  //     {
  //       while (Serial.available() > 0)
  //       {
  //         i++;
  //         receivebytes[i] = Serial.read();
  //     //    delay(2);
  //         if (receivebytes[i] == (uint8_t)0x23)
  //         {
  //           i++;
  //           receivebytes[i] = Serial.read();
  //        //   delay(2);
  //           if (receivebytes[i] == (uint8_t)0x23)
  //           {
  //             break;
  //           }
  //           else
  //           {
  //             continue;
  //           }

  //         }
  //         else
  //         {
  //           //continue the while
  //         }
  //       }

  //     }
  //   }
  // }

  int8_t i = 0;
  //获取主机的消息
  while (Serial.available()) {
    // get the new byte:
    receivebytes[i] = Serial.read();
    delay(2);
    if (receivebytes[0] !=  (uint8_t)0x24) {
      continue;
    }
    if (receivebytes[i] ==  (uint8_t)0x23) {
      i++;
      receivebytes[i] = Serial.read();
      delay(2);
      if (receivebytes[i] ==  (uint8_t)0x23) {
        break;
      }
    }
    i++;

  }
  delay(50);
  



  if (receivebytes[i] != (uint8_t)0x23 || receivebytes[0] != (uint8_t)0x24)
  {
    return false;
  }

  receiveLength = (uint8_t)(i + 1);

  return true;
}
//count the number of 1
uint8_t bitcount (uint8_t n)
{
  uint8_t count = 0 ;
  while (n)  {
    count++ ;
    n &= (n - 1) ;
  }
  return count ;
}

//getgetParityCheckByte_receive
uint8_t getREQParityCheckByte_receive()
{
  int Data_Length = receivebytes[3];
  uint8_t ParityCheckByte_receive = receivebytes[4 + Data_Length];
  return ParityCheckByte_receive;
}
uint8_t getRESParityCheckByte_receive()
{

  uint8_t ParityCheckByte_receive = receivebytes[5];
  return ParityCheckByte_receive;
}
void calculateParityCheckByte() {
  for (int i = 0; i < receiveLength - 4; i++)
  {
    receivebytes[i] = receivebytes[i + 2];
  }
  receiveLength = receiveLength - 4;

  uint8_t count[receiveLength];
  //count the numnber of "1" in each byte
  for (int j = 0; j < receiveLength - 1; j++)
  {
    count[j] = bitcount (receivebytes[j]);
    if (count[j] % 2)
    {
      count[j] = 1;
    }
    else
    {
      count[j] = 0;
    }

  }
  //add the ( numnber of "1" in each byte) if jishu ParityCheck_receive=0x01;
  uint8_t sum = 0;
  for (int w = 0; w < receiveLength - 1; w++)
  {

    sum = sum + count[w];
  }
  if (sum % 2)
  {
    ParityCheckByte_receive_calculate = (uint8_t)0x01;
  }
  else
  {
    ParityCheckByte_receive_calculate = (uint8_t)0x00;
  }

}
// 奇偶校验并区分请求与响应
uint8_t checkdata() {
  uint8_t ParityCheckByte_receive;
  calculateParityCheckByte();

  switch (receivebytes[0])
  {
    case 0x00:
      ParityCheckByte_receive = getREQParityCheckByte_receive();
      DMSG_STR_MINE("lalalalalalaldata received is");
        nfc.PrintHex_2(receivebytes, receiveLength);
      if (ParityCheckByte_receive_calculate != ParityCheckByte_receive)
      {

        DMSG_STR_MINE("error at ParityCheck in request");
        send_response_package(ParityCheck_error_status);
         delay(5);

        return 0;
      }
      else {
        return 2;
      }
      break;
    case 0x01:
      ParityCheckByte_receive = getRESParityCheckByte_receive();
      if (ParityCheckByte_receive_calculate != ParityCheckByte_receive)
      {
        DMSG_STR_MINE("error at ParityCheck");
        send_response_package(ParityCheck_error_status);
         delay(5);
        return 0;
      }
      else {
        return 1;
      }
      break;
    default:
      DMSG_STR_MINE("error at FLAG");
      send_response_package(FLAG_error_status);
       delay(5);
      return 0;
      break;
  }

}
bool checkstatus() {
  //check the status of response;
  //if(00),return true;
  //if(else).return false;
  uint8_t status_receive = receivebytes[2];
  if (status_receive == (uint8_t)0x00)
  { 
     DMSG_STR_MINE("insideof checkstatus receive success response ");
    delay(5);
    flag_has_received_successresponse=true;
    return true;
  }
  else
  {
    DMSG_STR_MINE("status_receive:");
    DMSG_STR_MINE(status_receive);
    return false;
  }
  return true;

}
bool checkRID() {
  uint8_t RID_receive = receivebytes[1];
  if (RID_receive == RID)
  {
    return true;
  }
  else
  {
    DMSG_STR_MINE("RID_receive:");
    DMSG_STR_MINE(RID_receive);
    return false;
  }
}
bool getDataFromPackage() {

  FLAG_2=receivebytes[2];
  for (int i = 0; i < receiveLength - 5; i++)
  {
    receivebytes[i] = receivebytes[i + 4];
  }
  receiveLength = receiveLength - 5;

  // DMSG_STR_MINE("the DATA length is "); DMSG_STR_MINE(receiveLength);
  // for(int i=0;i<(uint8_t)sizeof(selectApdu);i++)
  // {
  //  receivebytes[i]=selectApdu[i];
  // }
  // *receiveLength=(uint8_t)sizeof(selectApdu);

  //*receivebytes=(uint8_t)0xd3;
  //*receiveLength=(uint8_t)1;
  return true;
}

bool getDataFromLinux() {

  success = watingPackagefromLinux();
  if (!success) {
    DMSG_STR_MINE("error at watingPackagefromLinux");
   delay(5);
    return false;
  }
  else {
    success = getPackageFromLinux();
    // DMSG_STR_MINE("sendAPDU: 1");
    //Serial.write(receivebytes, receiveLength);
    if (!success)
    {
      DMSG_STR_MINE("error at getPackageFromLinux");
      delay(5);
      return false;
    }
    else {
      check_flag = checkdata();
      // DMSG_STR_MINE("sendAPDU: 2");
      // Serial.write(receivebytes, receiveLength);
      //the data received is error
      if (check_flag == 0) {
        flag_receive_res = false;
        DMSG_STR_MINE("error at checkdata");
        delay(5);
        return false;
      }
      //the data received is response
      else if (check_flag == 1)
      {
        flag_receive_res = true;
        DMSG_STR_MINE("receive  response ");
        delay(5);
        result = checkstatus();
        if (!result)
        {
          DMSG_STR_MINE("receive  error response ");
          delay(5);
          handlerror();
          if(numOfResend>2)
          {
            numOfResend=0;
          }
          return false;
        }
        else {
          numOfResend=0;
          DMSG_STR_MINE("receive success from response ");
          delay(5);
          return true;
        }
      }
      //the data received is request
      else {
         flag_receive_res = false;
        result = checkRID();
        //RID error
        if (!result)
        {
          DMSG_STR_MINE("error at checkRID ");
          send_response_package(RID_error_status);
           delay(5);
          return false;
        }
        //RID correct
        else {

          success = getDataFromPackage();

          if (!success)
          {
            DMSG_STR_MINE("error at getDataFromPackage");
            send_response_package(APDU_error_status);
             delay(5);
            return false;
          }
          else
          {
            //                   DMSG_STR_MINE("222the DATA received is ");
            //                Serial.write(receivebytes, receiveLength);
            //                    DMSG_STR_MINE("the DATA length is "); DMSG_STR_MINE(receiveLength);
            DMSG_STR_MINE("the response package is ");
             //setup();
            send_response_package(success_status);
            delay(5);
            
             
            return true;

          }
        }
      }
    }
  }
}
bool doDataExchange() {

  DMSG_STR_MINE("555the DATA received is ");
    delay(5);
  nfc.PrintHex_2(receivebytes, receiveLength);
  success = nfc.inDataExchange(receivebytes, receiveLength, response, &responseLength);

  if (!success)
  {
    DMSG_STR_MINE("Failed sending SELECT AID");
    //DMSG_STR_MINE("please remove the card and put it on the reader again");
    return false;
  }
  else {
    DMSG_MINE("responseLength_select: "); DMSG_STR_MINE(responseLength);
      delay(5);
    nfc.PrintHex_2(response, responseLength);
    DMSG_STR_MINE("sendAPDU: ");
      delay(5);
   nfc.PrintHex_2(receivebytes, receiveLength);

    send_APDU_request_data();
     delay(5);
    responseLength = 100;
    return true;
  }
}
bool readUID() {
  bool fsuccess;
  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  fsuccess = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);

  if (fsuccess) {

    // DMSG_STR_MINE("Found a card!");

    DMSG_MINE("UID Length: "); DMSG_MINE(uidLength, DEC); DMSG_STR_MINE(" bytes");
    DMSG_MINE("UID Value: ");
    nfc.PrintHex_2(uid,uidLength);
    return true;
  }
  else
  {
    DMSG_STR_MINE("Fail to get UID ");
    return false;
  }

}